package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.PayBalanceUserDao;
import com.xbongbong.saas.domain.entity.PayBalanceEntity;
import com.xbongbong.saas.domain.entity.PayBalanceUserEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.enums.PayBalanceEnum;
import com.xbongbong.saas.enums.subform.PayBalanceTeamEnum;
import com.xbongbong.saas.enums.subform.PaymentSheetTeamEnum;
import com.xbongbong.saas.model.PayBalanceUserModel;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author 徐俊杰
 * @date 2020/2/24 16:35
 * @since v1.0
 */
@Service("payBalanceUserModel")
public class PayBalanceUserModelImpl implements PayBalanceUserModel {
    @Resource
    private PayBalanceUserDao dao;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private TransferSubFormHelper transferSubFormHelper;

    @Override
    public Integer save(PayBalanceUserEntity PayBalanceUserEntity) throws XbbException {
        return null;
    }

    @Override
    public PayBalanceUserEntity getByKey(Long key, String corpid) {
        return null;
    }

    @Override
    public Integer deleteBatchByParentId(List<Long>  parentIdIn, String corpid) throws XbbException {
        Integer integer = 0;
        if(CollectionsUtil.isEmpty(parentIdIn)){
            return integer;
        }
        return deleteBatchByParentId(parentIdIn, corpid, DelEnum.DELETE.getDel());
    }

    private Integer deleteBatchByParentId(List<Long> parentIdIn, String corpid, Integer del) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("orderByStr", "id");
        param.put("pageSize", PaasConstant.ES_MAX_PAGE_SIZE);
        param.put("dataIdIn",parentIdIn);
        boolean flag = true;
        List<Long> idIn;
        Integer integer = 0;
        boolean delFlag = false;
        if(Objects.equals(DelEnum.DELETE.getDel(),del)){
            delFlag = true;
        }
        while (flag) {
            List<PayBalanceUserEntity> list = dao.findEntitys(param);
            if(CollectionsUtil.isEmpty(list)){
                return integer;
            }
            if (list.isEmpty()) {
                flag = false;
            } else {
                param.put("idGte", list.get(list.size() - 1).getId());
                List<InsertDTO> insertList = new ArrayList<>();
                idIn = new ArrayList<>(list.size());
                for (PayBalanceUserEntity PayBalanceUserEntity : list) {
                    idIn.add(PayBalanceUserEntity.getId());
                    InsertDTO insertDTO = new InsertDTO();
                    insertDTO.setEsId(IndexTypeEnum.IDX_PAY_BALANCE_TEAM.getType() + "_" + corpid + "_" + PayBalanceUserEntity.getId());
                    insertDTO.setParent(corpid + "_" + PayBalanceUserEntity.getDataId());
                    Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    //如果传进来的del=1则是要删除团队，否则是回滚ES，从数据库覆盖即可
                    if(delFlag){
                        map.put(ParameterConstant.DEL, DelEnum.DELETE.getDel());
                    }else{
                        map.put(ParameterConstant.DEL,PayBalanceUserEntity.getDel());
                    }
                    map.put(FieldTypeEnum.UPDATETIME.getAlias(), DateTimeUtil.getInt());
                    insertDTO.setSource(map);
                    insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_PAY_BALANCE_TEAM);
                    insertList.add(insertDTO);
                }
                //如果传进来的del=1则是要删除团队，否则是回滚ES，从数据库覆盖即可，不需要更新数据库
                if(delFlag){
                    if(CollectionsUtil.isEmpty(idIn)){
                        return integer;
                    }
                    integer = dao.deleteBatch(idIn, corpid);
                }
                paasEsModel.updateBatch(insertList);
            }
        }
        return integer;
    }

    @Override
    public Integer deleteBatchRollbackByParentId(List<Long> parentIdIn, String corpid) throws XbbException {
        Integer integer = 0;
        if(CollectionsUtil.isEmpty(parentIdIn)){
            return integer;
        }
        return deleteBatchByParentId(parentIdIn, corpid, DelEnum.NORMAL.getDel());
    }

    @Override
    public void disbandedTeamBySupplierId(String corpid, List<Long> supplierIdIn) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(PayBalanceEnum.SUPPLIER_ID.getAttr(),supplierIdIn));
        List<PayBalanceEntity> paasFormDataEntityList = esHelper.findByScroll(IndexTypeEnum.IDX_PAY_BALANCE,boolQueryBuilder, PayBalanceEntity.class, Collections.singletonList(StringConstant.SAAS_LINK_BUSINESS_ID));
        if (paasFormDataEntityList.isEmpty()){
            return;
        }
        List<Long> idList = new ArrayList<>();
        for (PayBalanceEntity entity : paasFormDataEntityList){
            idList.add(entity.getId());
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("del",0);
        map.put("dataIdIn",idList);
        List<PayBalanceUserEntity> payBalanceUserEntityList = findEntitys(map);
        List<Long> idIn = new ArrayList<>(payBalanceUserEntityList.size());
        for (PayBalanceUserEntity payBalanceUserEntity : payBalanceUserEntityList) {
            idIn.add(payBalanceUserEntity.getId());
        }
        batchUpdateByUserIds(corpid,idIn,payBalanceUserEntityList,null,1);
    }

    @Override
    public Integer insert(PayBalanceUserEntity entity) throws XbbException {
        long now = DateTimeUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        Integer result = dao.insert(entity);
        PaasFormDataEntity paasFormDataEntity = transferSubFormHelper.transferUserTeamToFormData(IndexTypeEnum.IDX_PAY_BALANCE_TEAM, entity);
        InsertDTO saveDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_PAY_BALANCE_TEAM);
        paasEsModel.insert(saveDTO);
//        paasEsModel.insert(entity, IndexTypeEnum.IDX_PAY_BALANCE_TEAM,entity.getCorpid(),entity.getId(),entity.getDataId());
        return result;
    }

    @Override
    public Integer update(PayBalanceUserEntity entity) throws XbbException {
        return null;
    }

    @Override
    public List<PayBalanceUserEntity> findEntitys(Map<String, Object> param) {
        return dao.findEntitys(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return dao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public List<UserTeamEntity> findBaseEntitys(Map<String, Object> map) {
        return dao.findBaseEntitys(map);
    }

    @Override
    public void insertBatch(List<PayBalanceUserEntity> payBalanceUserEntityList) throws XbbException {
        insertBatch(payBalanceUserEntityList, WriteRequest.RefreshPolicy.NONE);
    }

    @Override
    public void insertBatch(List<PayBalanceUserEntity> payBalanceUserEntityList, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        dao.insertBatch(payBalanceUserEntityList);
        List<PaasFormDataEntity> paasFormDataEntities = transferSubFormHelper.transferUserTeamToFormDataList(IndexTypeEnum.IDX_PAY_BALANCE_TEAM, payBalanceUserEntityList);

        List<InsertDTO> insertDTOList = new ArrayList<>();
        for (PaasFormDataEntity paasFormDataEntity : paasFormDataEntities) {
            insertDTOList.add(paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_PAY_BALANCE_TEAM));
        }
        paasEsModel.insertBatch(insertDTOList, refreshPolicy);
    }


    @Override
    public void batchUpdateByUserIdIn(String corpid, List<Long> idIn, List<UserTeamEntity> teamEntityList, Integer isMain, Integer del) throws XbbException {
        batchUpdateByUserIdIn(corpid, idIn, teamEntityList, isMain, del, WriteRequest.RefreshPolicy.WAIT_UNTIL);
    }

    @Override
    public void batchUpdateByUserIdIn(String corpid, List<Long> idIn, List<UserTeamEntity> teamEntityList, Integer isMain, Integer del, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        dao.batchUpdateByIdIn(corpid,idIn,isMain,del);
        List<InsertDTO> insertList = new ArrayList<>();
        for (UserTeamEntity userTeamEntity : teamEntityList) {
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_PAY_BALANCE_TEAM.getType() + "_" + corpid + "_" + userTeamEntity.getId());
            insertDTO.setParent(corpid + "_" + userTeamEntity.getDataId());
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(isMain)) {
                JSONObject object = new JSONObject();
                object.put(PayBalanceTeamEnum.IS_MAIN.getDataAttr(), isMain);
                map.put(StringConstant.JSON_DATA, object);
            }
            if (Objects.nonNull(del)) {
                map.put(ParameterConstant.DEL, del);
            }
            map.put(FieldTypeEnum.UPDATETIME.getAlias(), DateTimeUtil.getInt());
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_PAY_BALANCE_TEAM);
            insertList.add(insertDTO);
        }
        paasEsModel.updateBatch(insertList, refreshPolicy);
    }


    @Override
    public void batchUpdateByUserIds(String corpid, List<Long> idIn, List<PayBalanceUserEntity> teamEntityList, Integer isMain, Integer del) throws XbbException {
        dao.batchUpdateByIdIn(corpid,idIn,isMain,del);
        List<InsertDTO> insertList = new ArrayList<>();
        for (PayBalanceUserEntity userTeamEntity : teamEntityList) {
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_PAY_BALANCE_TEAM.getType() + "_" + corpid + "_" + userTeamEntity.getId());
            insertDTO.setParent(corpid + "_" + userTeamEntity.getDataId());
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(isMain)) {
                JSONObject object = new JSONObject();
                object.put(PayBalanceTeamEnum.IS_MAIN.getDataAttr(), isMain);
                map.put(StringConstant.JSON_DATA, object);
            }
            if (Objects.nonNull(del)) {
                map.put(ParameterConstant.DEL, del);
            }
            map.put(FieldTypeEnum.UPDATETIME.getAlias(), DateTimeUtil.getInt());
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_PAY_BALANCE_TEAM);
            insertList.add(insertDTO);
        }
        paasEsModel.updateBatch(insertList);
    }

    @Override
    public void deleteBatchUser(List<PayBalanceUserEntity> payBalanceUserEntityList, String corpid) throws XbbException {
        if(CollectionsUtil.isEmpty(payBalanceUserEntityList)){
            return;
        }
        List<Long> idIn = new ArrayList<>(payBalanceUserEntityList.size());
        for (PayBalanceUserEntity payBalanceUserEntity : payBalanceUserEntityList) {
            idIn.add(payBalanceUserEntity.getId());
        }
        batchUpdateByUserIds(corpid,idIn,payBalanceUserEntityList,null,1);
    }

    /**
     * 批量更新团队的人员为协同人身份以及协同人的可编辑权限
     *
     * @param corpid
     * @param dataIdIn
     * @param teamEntityList
     * @param isMain
     * @param needThrow
     * @throws XbbException
     */
    @Override
    public void batchUpdateCoAndPerByUserIdIn(String corpid, List<Long> dataIdIn, List<UserTeamEntity> teamEntityList, Integer isMain, boolean needThrow) throws XbbException {
        batchUpdateCoAndPerByUserIdIn(corpid, dataIdIn, teamEntityList, isMain, needThrow, WriteRequest.RefreshPolicy.WAIT_UNTIL);
    }

    @Override
    public void batchUpdateCoAndPerByUserIdIn(String corpid, List<Long> dataIdIn, List<UserTeamEntity> teamEntityList, Integer isMain, boolean needThrow, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        Integer formPermission = teamEntityList.get(BasicConstant.ZERO).getFormPermission();
        dao.batchUpdateCoAndPerByUserIdIn(corpid, dataIdIn, isMain, formPermission);
        List<InsertDTO> insertList = new ArrayList<>();
        for (UserTeamEntity userTeamEntity : teamEntityList) {
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_PAY_BALANCE_TEAM.getType() + "_" + corpid + "_" + userTeamEntity.getId());
            insertDTO.setParent(corpid + "_" + userTeamEntity.getDataId());
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(isMain)) {
                JSONObject object = new JSONObject();
                object.put(PaymentSheetTeamEnum.IS_MAIN.getDataAttr(), isMain);
                map.put(StringConstant.JSON_DATA, object);
            }
            map.put(FieldTypeEnum.UPDATETIME.getAlias(), DateTimeUtil.getInt());
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_PAY_BALANCE_TEAM);
            insertList.add(insertDTO);
        }
        paasEsModel.updateBatch(insertList, refreshPolicy, needThrow);
    }

    /**
     * 获取需要处理的公司
     *
     * @return
     */
    @Override
    public List<String> getAllCorpList() {
        return dao.getAllCorpList();
    }
}
